﻿namespace Agile.Infra.Repository;

public partial class BaseModel : INotifyPropertyChanged
{
    public BaseModel()
    {
    }

    public BaseModel(bool enabledPropertyChanged) => _enabledPropertyChanged = enabledPropertyChanged;

    private bool _enabledPropertyChanged = false;

    private ChangedPropertyCollection _changedPropertys;
    /// <summary>存储被修改过的属性</summary>
    [XmlIgnore, IgnoreDataMember]
    [Newtonsoft.Json.JsonIgnore, System.Text.Json.Serialization.JsonIgnore]
    protected internal ChangedPropertyCollection ChangedPropertys
    {
        get
        {
            if (_changedPropertys == null) _changedPropertys = new ChangedPropertyCollection();
            return _changedPropertys;
        }
    }

    /// <summary>属性改变事件</summary>
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>属性改变</summary>
    /// <param name="propertyName">属性名</param>
    protected virtual void OnPropertyChanged([CallerMemberName] String propertyName = null)
    {
        if (_enabledPropertyChanged == false || propertyName == null) return;
        ChangedPropertys[propertyName] = true;
        PropertyChanged?.Invoke(propertyName, new PropertyChangedEventArgs(propertyName));
    }

    public int PropertyChangedCount() => _changedPropertys == null ? 0 : _changedPropertys.Count;

    /// <summary>查检属性值是否改变</summary>
    /// <param name="propertyName">字段名</param>
    public bool IsChanged(string propertyName = null) => _enabledPropertyChanged && ChangedPropertys.Contains(propertyName);

    public virtual async Task<string> ToLogAsync(BaseModel oldModel, IServiceProvider serviceProvider)
    {
        if (_enabledPropertyChanged == false)
        {
            return string.Empty;
        }
        return await ToLogAsync(this, oldModel, serviceProvider);
    }

    public virtual async Task<string> ToLogAsync(string operationName, BaseModel oldModel, IServiceProvider serviceProvider)
    {
        var logContent = await ToLogAsync(oldModel, serviceProvider);
        if (logContent.IsNullOrWhiteSpace())
        {
            return string.Empty;
        }
        return $"{operationName}：{logContent}";
    }

    protected virtual async Task<string> ToLogAsync(BaseModel newBaseModel, BaseModel oldBaseModel, IServiceProvider serviceProvider)
    => await Task.FromResult(string.Empty);
}